<template>
  <div class="content-wrap content-container" v-loading="loading">
    <!-- 搜索区域 -->
    <el-form class="search-wrap" v-model="searchFormData">
      <el-form-item class="search-wrap-item" label="标题关键字：" prop="projectTitle">
        <el-input min-width="360px" placeholder="请输入标题关键字" v-model="searchFormData.projectTitle" clearable
          @keyup.enter="getAllRequirements"></el-input>
      </el-form-item>
      <!-- 标签筛选 -->
      <el-form-item class="search-wrap-item" label="标签：" prop="tag">
        <el-select v-model="searchFormData.tag" placeholder="请选择标签" clearable @change="handleTagFilter"
          style="width: 240px">
          <el-option v-for="tag in allTags" :key="tag" :label="tag" :value="tag" />
        </el-select>
      </el-form-item>
      <el-form-item class="search-wrap-item" label="归属人：" prop="userName">
        <el-input min-width="360px" placeholder="请输入归属人" v-model="searchFormData.userName" clearable
          @keyup.enter="getAllRequirements"></el-input>
      </el-form-item>
      <el-form-item class="search-wrap-item" label="时间：" prop="time">
        <el-date-picker style="width: 240px" type="daterange" unlink-panels range-separator="-" start-placeholder="开始时间"
          end-placeholder="结束时间" :value-on-clear="null" v-model="searchFormData.time" format="YYYY-MM-DD"
          value-format="YYYY-MM-DD" @change="getAllRequirements" />
      </el-form-item>
    </el-form>

    <!-- [我负责的需求]列表区域 -->
    <div class="card-layout-box" id="cardLayoutBox">
      <div class="card-not-requirement" v-if="allRequirements.length === 0">
        暂无数据
      </div>
      <!-- 分类 -->
      <div v-if="allRequirements.length !== 0" class="card-box" v-for="(list, index) in allRequirements" :key="index">
        <div class="card-header-box">
          <el-tag :style="{ backgroundColor: fatherStatus(list.status)?.bgColor }">{{ fatherStatus(list.status).text
          }}</el-tag> - {{ list.total }}
        </div>
        <!-- 需求列表 -->
        <div class="card-list-box" :id="`card-list-box-${list.status}`" @scroll="handleScroll(list.status)">
          <ul class="card-list">
            <li class="card-list-item" v-for="item in list.requirements" :key="item.ID"
              :class="{ 'red-bj': item.isOutTime === '是' }">
              <div class="card-list-left">
                <!-- 延期图标 -->
                <div class="icon-img" v-if="item.isOutTime === '是'">
                  <img src="../../../assets/images/icon-delay.png" style="width: 50px;" />
                </div>
                <!-- 需求类别 -->
                <div class="card-list-type">
                  <span>
                    <el-icon :style="{ color: taskTypeContent(item.taskType).color }" :size="14">
                      <Flag />
                    </el-icon>
                    {{ taskTypeContent(item.taskType).text }}
                  </span>
                  <!-- <span>
                    <el-icon :style="{ color: isTsContent(item.isTs).color }" :size="15">
                      <Flag />
                    </el-icon>
                    {{ isTsContent(item.isTs).text }}
                  </span> -->
                </div>
                <!-- 需求标题 -->
                <div class="card-header-title-box" @click="handleRowClick(item.ID)"
                  :class="{ 'card-finished': item.requirementFatherStatus === 9 }">
                  <b>{{ item.requirementName }}</b>
                </div>
                <!-- 附加信息：样式二 -->
                <div class="w-[100%] text-[12px] flex flex-col pl-[5px] pr-[5px]" style="color: #999;">
                  <!-- 审核人、技术负责人、测试负责人 -->
                  <div class="w-[100%] flex flex-row">
                    <!-- <p class="mr-5 w-7/32 truncate" v-if="item.requirementCreateName">创建人：{{ item.requirementCreateName
                      }}</p> -->
                    <p class="mr-[5px] w-[33%] truncate" v-if="item.requirementAuditName">审核人：{{
                      item.requirementAuditName }}
                    </p>
                    <p class="mr-[5px] w-[33%] truncate" v-if="item.requirementBossName">技术负责人：{{
                      item.requirementBossName }}
                    </p>
                    <p class=" w-[33%] truncate" v-if="item.contactTestBossName">测试负责人：{{ item.contactTestBossName }}
                    </p>
                  </div>

                  <!-- 参与研发、运维、测试 -->
                  <div class="w-[100%] flex flex-row" v-if="item.requirementFatherStatus !== 1">
                    <p class="mr-[5px] w-[33%] truncate"
                      v-if="(item.requirementRelevances == '' && item.requirementLinuxs == '')">
                      <span class="text-[red]">未分配研发/运维</span>
                    </p>
                    <p class="mr-[5px] w-[33%] truncate" v-if="item.requirementRelevances || item.requirementLinuxs">
                      研发：{{
                        item.requirementRelevances ? handleStringNames(item.requirementRelevances) : '无' }}</p>
                    <p class="mr-[5px] w-[33%] truncate" v-if="item.requirementRelevances || item.requirementLinuxs">{{
                      item.requirementLinuxs ? `${"运维："+handleStringNames(item.requirementLinuxs)}` : "运维：无" }}</p>
                    <p class="w-[33%] truncate" v-if="item.isGetTest == 2 && item.contactTestNames !== ''">测试：{{
                      handleStringNames(item.contactTestNames) }}</p>
                    <p class="w-[33%] truncate" v-if="item.isGetTest == 1">
                      <span class="text-[red]">不需要测试参与</span>
                    </p>
                    <p class="w-[33%] truncate"
                      v-if="(item.isGetTest == 2 && item.contactTestNames == '') || item.isGetTest == 3">
                      <span class="text-[red]">未分配测试</span>
                    </p>
                  </div>
                </div>

                <!-- 上线状态、评论状态 -->
                <div class="card-stats">
                  <span v-if="item.requirementFatherStatus == 8"
                    :style="{ color: item.requirementOnlineStatus == 1 ? '#2d8cf0' : item.requirementOnlineStatus == 3 ? 'red' : 'green' }">
                    {{ item.requirementOnlineStatus == 1 ? '待确认上线状态' : item.requirementOnlineStatus == 2 ? '上线成功' :
                      '上线失败' }}
                  </span>
                  <span v-if="userAuthId == '555'" :style="{ color: item.tipDevOnlineStatus == 1 ? 'red' : 'green' }">{{
                    item.tipDevOnlineStatus
                      == 1 ? '未评论' : '已评论' }}</span>
                  <span v-if="userAuthId == '111'" :style="{ color: item.tipTsOnlineStatus == 1 ? 'red' : 'green' }">{{
                    item.tipTsOnlineStatus ==
                      1 ? '未评论' : '已评论' }}</span>
                  <span v-if="userAuthId !== '555' && userAuthId !== '111'"
                    :style="{ color: item.tipDevOnlineStatus == 1 ? 'red' : 'green' }">{{ item.tipDevOnlineStatus
                      == 1 ? '研发未评论' : '研发已评论' }}</span>
                  <span v-if="userAuthId !== '555' && userAuthId !== '111'"
                    :style="{ color: item.tipTsOnlineStatus == 1 ? 'red' : 'green' }">{{ item.tipTsOnlineStatus ==
                      1 ? '测试未评论' : '测试已评论' }}</span>
                </div>
                <!-- 时间 -->
                <div class="card-list-small-item begin-time">
                  <!-- 任务时间 -->
                  <el-icon>
                    <Clock style="position: absolute;left: 0;top:2px;" />
                  </el-icon>
                  <span>{{ timeToData(item.createAt) }}</span>
                  <span v-if="item.onlineTime"> - </span>
                  <span :class="{ 'red-text': item.isOutTime === '是' }">{{ timeToData(item.onlineTime) }}</span>
                </div>
              </div>

              <!-- 操作 -->
              <div class="operate-box">
                <el-dropdown :hide-on-click="false" placement="bottom" @command="handleCommand">
                  <span class="el-dropdown-link">
                    <el-icon class="el-icon--right" color="#409EFF">
                      <MoreFilled />
                    </el-icon>
                  </span>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <!-- 研发负责人分配研发任务操作 -->
                      <el-dropdown-item v-if="item.requirementFatherStatus == 1 && (userAuthId == '555' || userAuthId == '888' || userAuthId == '999')
                      " :command="{
                        requirement: item,
                        operate: fatherStatus(item.requirementFatherStatus).status,
                        operate2: 1
                      }">
                        {{
                          (item.itemRequirementWorldSummary == "" && (item.taskType == 1 || item.taskType == 3))
                            ? "上传概要设计"
                            : (item.isGetTest == 3)
                              ? "操作"
                              : fatherStatus(item.requirementFatherStatus).operate
                        }}
                      </el-dropdown-item>

                      <!-- 分配按钮 - 状态2(待开发)和状态6(待上线评审) -->
                      <el-dropdown-item
                        v-if="(item.requirementFatherStatus == 2 || item.requirementFatherStatus == 6) &&
                          (userAuthId == '555' || userAuthId == '888' || userAuthId == '999') && 
                          (item.requirementRelevances == '')"
                        :command="{ requirement: item, operate: 1, operate2: 1 }">
                        分配
                      </el-dropdown-item>
                      <!-- 如果用户为测试负责人,分配测试人员 -->
                      <el-dropdown-item v-if="
                        userAuthId == '111' &&
                        item.contactTestNames == '' && item.taskType == 1 &&
                        (item.requirementFatherStatus < 4 || item.requirementFatherStatus == 6)
                      " :command="{ requirement: item, operate: 1, operate2: 1 }">
                        {{ fatherStatus(1).operate }}
                      </el-dropdown-item>

                      <el-dropdown-item v-if="
                        userAuthId == '111' &&
                        item.contactTestNames == '' && item.taskType !== 1
                      " :command="{ requirement: item, operate: 1, operate2: 1 }">
                        {{ fatherStatus(1).operate }}
                      </el-dropdown-item>

                      <!-- 研发负责人提交上线结果 -->
                      <el-dropdown-item v-if="
                        (userAuthId == '555' || userAuthId == '999') &&
                        item.requirementFatherStatus == 8 && item.requirementOnlineStatus == 1
                      " :command="{ requirement: item, operate: 8, operate2: 2 }">
                        <!-- {{ fatherStatus(item.requirementFatherStatus).operate }} -->
                        上线结果
                      </el-dropdown-item>

                      <!-- 研发负责人对上线研发和运维的评语 -->
                      <el-dropdown-item v-if="
                        item.requirementFatherStatus == 8 &&
                        (userAuthId == '555' || userAuthId == '888' || userAuthId == '999')
                      " :command="{ requirement: item, operate: 8, operate2: 1 }">
                        {{
                          item.tipDevOnlineStatus == 1
                            ? fatherStatus(item.requirementFatherStatus).operate
                            : "查看评分"
                        }}
                      </el-dropdown-item>

                      <!-- 测试负责人对上线测试的评语 -->
                      <el-dropdown-item v-if="
                        item.requirementFatherStatus == 8 &&
                        userAuthId == '111'
                      " :command="{ requirement: item, operate: 8, operate2: 1 }">
                        {{
                          item.tipTsOnlineStatus == 1
                            ? fatherStatus(item.requirementFatherStatus).operate
                            : "查看评分"
                        }}
                      </el-dropdown-item>

                      <!-- 已关闭的需求撤回操作 -->
                      <el-dropdown-item v-if="item.requirementFatherStatus == 9"
                        :command="{ requirement: item, operate: 9 }">
                        {{ fatherStatus(item.requirementFatherStatus).operate }}
                      </el-dropdown-item>

                      <!-- 关闭操作 -->
                      <el-dropdown-item v-if="
                        item.requirementFatherStatus !== 9 &&
                        item.requirementFatherStatus !== 8
                      " :command="{ requirement: item, operate: 9 }">关闭</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </li>
            <!-- 懒加载状态指示器 -->
            <li v-if="statusLoadingStates[list.status]" class="loading-indicator">
              <div class="loading-content">
                <el-icon class="is-loading">
                  <Loading />
                </el-icon>
                <span>加载中...</span>
              </div>
            </li>
            <li v-else-if="!statusHasMoreStates[list.status] && list.requirements.length > 0" class="no-more-data">
              <div class="no-more-content">
                没有更多数据了
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <!-- 上传概要设计 -->
    <el-dialog class="dialog-container" style="
        min-height: 400px;
        display: flex;
        justify-content: space-between;
        flex-direction: column;" v-model="dialogDesignFileVisible" title="上传概要设计" @close="handleCloseDialog"
      @closed="handleCloseDialog">
      <div style="width: 100%;">
        <el-button style="margin-bottom: 10px;" type="primary" size="small" plain
          @click="openModal = true">关联文件</el-button>
        <UploadFilesVue :initConfig="initConfig" @updateFilePaths="handleUpdateFilePaths" :resetFiles="resetFiles">
        </UploadFilesVue>
      </div>



      <!-- 关联的文件 -->
      <div
        style="margin-top: 10px;width: 100%;height: 500px; display: flex;flex-direction: column;flex-wrap: nowrap; overflow-y: auto;">
        <el-tag style="margin-bottom: 5px;display: flex;justify-content: space-between;margin-right: 10px;"
          v-for="(file, index) in newAssFilesList" :key="index" closable :disable-transitions="false"
          @close="handleDelAssFile(file)">
          {{ handleFileName(file).fileName }}
        </el-tag>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleCloseDialog">取消</el-button>
          <el-button type="primary" @click="handleDesignFile(isRequirementID)">提交</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 判断是否需求测试参与、对项目经理评价、对需求评分 -->
    <el-dialog class="dialog-container" v-model="dialogIsGetTestPMTipVisible"
      :title="isRequirementData?.requirementName" :close-on-click-modal="false" @close="handleCloseResetDialog"
      @closed="handleCloseResetDialog">
      <el-form class="dialog-isGetTest-form" label-width="180px" label-position="left" ref="isGetTestPMTipRef"
        :rules="isGetTestPMTipRules" :model="isGetTestPMTipForm">
        <!-- 是否需要测试参与 -->
        <el-form-item label="是否需要测试参与：" prop="isGetTest" required>
          <el-switch style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" size="large"
            v-model="isGetTestPMTipForm.isGetTest" inline-prompt active-text="需要" inactive-text="不需要" :active-value=2
            :inactive-value=1 />
        </el-form-item>
        <!-- 对项目经理评分 -->
        <el-form-item label="对【项目经理】评分：" prop="itemRequirementPMNumber">
          <el-input-number size="defalut" :min="0" :precision="0" v-model="isGetTestPMTipForm.itemRequirementPMNumber"
            controls-position="right" />
          （备注：评分分值：1-100；针对这个需求，项目经理在处理时是否积极，沟通解决问题等等...）
        </el-form-item>
        <!-- 对项目经理评价 -->
        <el-form-item label="对【项目经理】评语：" prop="itemRequirementPMTip">
          <el-input type="textarea" rows="4" maxlength="200" show-word-limit
            v-model="isGetTestPMTipForm.itemRequirementPMTip" placeholder="请输入对【项目经理】的评语...">
          </el-input>
        </el-form-item>
        <!-- 对需求评分 -->
        <el-form-item label="对该需求【复杂难度】评分：" prop="itemRequirementProjectPMNumber">
          <el-input-number size="defalut" :min="0" :precision="0"
            v-model="isGetTestPMTipForm.itemRequirementProjectPMNumber" controls-position="right" />
          <span style="color: red;font-size: 12px;">（备注：评分分值：1-100；如任务复杂且无法拆分，分值无上限，例如：200,300,400,500等...）</span>
        </el-form-item>
        <!-- 对需求评价 -->
        <el-form-item label="对该需求【复杂难度】评语：" prop="itemRequirementProjectPMTip">
          <el-input type="textarea" rows="4" maxlength="200" show-word-limit
            v-model="isGetTestPMTipForm.itemRequirementProjectPMTip" placeholder="请输入对该需求【复杂难度】评语...">
          </el-input>
        </el-form-item>
        <!-- 表单操作 -->
        <el-form-item>
          <!-- <template #="defalut"> -->
          <div class="dialog-footer">
            <el-button type="defalut" @click="handleCloseResetDialog">取消</el-button>
            <el-button type="primary" @click="submitIsGetTestPMTipForm(isGetTestPMTipRef)">提交</el-button>
          </div>
          <!-- </template> -->
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 分配任务弹窗 -->
    <el-dialog class="dialog-container" style="
        max-height: 700px;
        display: flex;
        justify-content: space-between;
        flex-direction: column;
        flex-wrap: nowrap;
      " width="1300px" :close-on-click-modal="false" v-model="dialogAvgVisible" title="分配任务"
      @close="handleCloseAssDialog" @closed="handleCloseAssDialog">

      <!-- 需求结束时间 -->
      <div class="block" style="margin-bottom: 20px"
        v-if="isRequirementData.requirementCreateName == '刘涛' || isRequirementData.requirementCreateName == '胡文斌' || userAuthId == '555' || userAuthId == '999' || userAuthId == '888'">
        <span class="demonstration">需求结束时间：</span>
        <el-date-picker v-model="endTime" type="date" placeholder="需求结束时间" :default-value="null"
          :disabledDate="disabledDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
        <p><span style="color: red; font-size: 12px;">（超时未完成即为需求超时!）</span></p>
      </div>

      <!-- 研发负责人分配研发任务或运维任务 -->
      <div style="overflow-y: auto; max-height: 580px"
        v-if="(userAuthId == '555' || userAuthId == '888' || userAuthId == '999')">
        <div>
          <!-- 1、分配研发任务 -->
          <div class="dialog-form-title">
            <div>
              <span>分配研发任务：</span>
            </div>
            <div>
              <el-button type="primary" size="small" @click="handleAddFormData(1)">
                添加
              </el-button>
            </div>
          </div>
          <el-form class="dialog-form-box" :model="devsRequirementFormData"
            v-for="(item, index) in devsRequirementFormData" :key="index">
            <!-- 研发人员 -->
            <el-form-item prop="userUUID">
              <el-select v-model="item.userUUID" filterable placeholder="参与人员" style="width: 100px" clearable>
                <el-option v-for="test in allDevNameOptions" :key="test.uuid" :label="test.nickName" :value="test.uuid"
                  :disabled="isDisabled(test.uuid, item.userUUID, 1)" />
              </el-select>
            </el-form-item>
            <!-- 预计完成时间 -->
            <el-form-item prop="guessTime">
              <el-date-picker style="width: 140px" v-model="item.guessTime" type="date" placeholder="预计完成时间"
                :disabledDate="disabledDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
            </el-form-item>
            <!-- 描述工作内容 -->
            <el-form-item prop="processJob">
              <el-input style="width: 420px" placeholder="简述工作内容..." clearable v-model="item.processJob"></el-input>
            </el-form-item>
            <!-- 评估耗时 -->
            <el-form-item prop="guessProcess">
              预计耗时：
              <el-input-number style="width: 80px" v-model="item.guessProcess" :min="1" controls-position="right" />
              &nbsp;&nbsp;小时
            </el-form-item>
            <!-- 需求评分 -->
            <el-form-item prop="processJobNum">
              任务难度评分：
              <el-input-number style="width: 80px" v-model="item.processJobNum" :min="0" :max="500"
                controls-position="right" />
            </el-form-item>
            <!-- 新增/删除操作按钮 -->
            <el-form-item>
              <el-button style="margin-top: 5px;" type="danger" :icon="Delete" size="small"
                @click="handleDelFormData(index, 1)" />
            </el-form-item>
          </el-form>
        </div>

        <!-- 2、分配运维任务 -->
        <div>
          <!-- 1、分配研发任务 -->
          <div class="dialog-form-title">
            <div>
              <span>分配运维任务：</span>
            </div>
            <div>
              <el-button type="primary" size="small" @click="handleAddFormData(2)">
                添加
              </el-button>
            </div>
          </div>
          <el-form class="dialog-form-box" :model="msRequirementFormData" v-for="(item, index) in msRequirementFormData"
            :key="index">
            <!-- 运维人员 -->
            <el-form-item prop="userUUID">
              <el-select v-model="item.userUUID" filterable placeholder="参与人员" style="width: 100px" clearable>
                <el-option v-for="test in allMsNameOptions" :key="test.uuid" :label="test.nickName" :value="test.uuid"
                  :disabled="isDisabled(test.uuid, item.userUUID, 2)" />
              </el-select>
            </el-form-item>
            <!-- 预计完成时间 -->
            <el-form-item prop="guessTime">
              <el-date-picker style="width: 140px" v-model="item.guessTime" type="date" placeholder="预计完成时间"
                :disabledDate="disabledDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
            </el-form-item>
            <!-- 描述工作内容 -->
            <el-form-item prop="processJob">
              <el-input style="width: 420px" placeholder="简述工作内容..." clearable v-model="item.processJob"></el-input>
            </el-form-item>
            <!-- 评估耗时 -->
            <el-form-item prop="guessProcess">
              预计耗时：
              <el-input-number style="width: 80px" v-model="item.guessProcess" :min="1" controls-position="right" />
              &nbsp;&nbsp;小时
            </el-form-item>
            <!-- 需求评分 -->
            <el-form-item prop="processJobNum">
              任务难度评分：
              <el-input-number style="width: 80px" v-model="item.processJobNum" :min="0" :max="500"
                controls-position="right" />
            </el-form-item>
            <!-- 新增/删除操作按钮 -->
            <el-form-item>
              <el-button style="margin-top: 5px;" type="danger" :icon="Delete" size="small"
                @click="handleDelFormData(index, 2)" />
            </el-form-item>
          </el-form>
        </div>
      </div>

      <!-- 3、测试负责人分配测试任务 -->
      <div style="overflow-y: auto; max-height: 580px" v-if="(userAuthId == '111')">
        <!-- 分配测试任务 -->
        <div class="dialog-form-title">
          <div>分配测试任务：</div>
          <div>
            <el-button type="primary" size="small" @click="handleAddFormData(3)">
              添加
            </el-button>
          </div>
        </div>
        <el-form class="dialog-form-box" :model="tsRequirementFormData" v-for="(item, index) in tsRequirementFormData"
          :key="index">
          <!-- 测试人员 -->
          <el-form-item prop="userUUID">
            <el-select v-model="item.userUUID" filterable placeholder="参与人员" style="width: 100px" clearable>
              <el-option v-for="test in allTestNameOptions" :key="test.uuid" :label="test.nickName" :value="test.uuid"
                :disabled="isDisabled(test.uuid, item.userUUID, 3)" />
            </el-select>
          </el-form-item>
          <!-- 预计完成时间 -->
          <el-form-item prop="guessTime">
            <el-date-picker style="width: 140px" v-model="item.guessTime" type="date" placeholder="预计完成时间"
              :disabledDate="disabledDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
          </el-form-item>
          <!-- 描述工作内容 -->
          <el-form-item prop="processJob">
            <el-input style="width: 420px" placeholder="简述工作内容..." clearable v-model="item.processJob"></el-input>
          </el-form-item>
          <!-- 评估耗时 -->
          <el-form-item prop="guessProcess">
            预计耗时：
            <el-input-number style="width: 80px" v-model="item.guessProcess" :min="1" controls-position="right" />
            &nbsp;&nbsp;小时
          </el-form-item>
          <!-- 需求评分 -->
          <el-form-item prop="processJobNum">
            任务难度评分：
            <el-input-number style="width: 80px" v-model="item.processJobNum" :min="0" :max="500"
              controls-position="right" />
          </el-form-item>
          <!-- 新增/删除测试操作按钮 -->
          <el-form-item>
            <el-button style="margin-top: 5px;" type="danger" :icon="Delete" size="small"
              @click="handleDelFormData(index, 3)" />
          </el-form-item>
        </el-form>
      </div>

      <!-- 操作区域 -->
      <template #footer>
        <div class="dialog-footer">
          <el-button type="default" @click="handleCloseAssDialog">取消</el-button>
          <el-button type="primary" @click="handleConfirmAvg">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 技术负责人填写上线结果 -->
    <el-dialog class="dialog-container" style="width: 800px" v-model="dialogOfflineToEndVisible" title="上线结果"
      :close-on-click-modal="false" @close="handleCloseOnlineDialog" @closed="handleCloseOnlineDialog">
      <el-form ref="offlineToEndFomrRef" :rules="offlineToEndFormRules" :model="offlineToEndForm" label-width="90px">
        <el-form-item label="上线结果：" porp="requirementOnlineStatus">
          <el-radio-group v-model="offlineToEndForm.requirementOnlineStatus" size="small">
            <el-radio :value="2" border>成功</el-radio>
            <el-radio :value="3" border>失败</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="说明：" :required="offlineToEndForm.requirementOnlineStatus == 3" porp="requirementOnlineMsg">
          <el-input maxlength="500" placeholder="请输入内容..." show-word-limit type="textarea" :rows="10"
            v-model="offlineToEndForm.requirementOnlineMsg" />
        </el-form-item>
        <el-form-item>
          <div class="dialog-footer">
            <el-button type="defalut" @click="handleCloseOnlineDialog">取消</el-button>
            <el-button type="primary" @click="handleSubmitOffline()">确定</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 技术负责人/测试负责人对上线参与人评价 -->
    <el-dialog class="dialog-online-container" style="
        width: 800px;
        max-height: 780px;
        margin-top: 50px;
      " :close-on-click-modal="false" v-model="dialogOfflineEndCotentVisible" :title="isOnlineContent ? '评分' : '查看'"
      @close="handleCloseOnlineContentDialog" @closed="handleCloseOnlineContentDialog">
      <!-- 上线结果及说明 -->
      <div class="online-outcome">
        <p class="online-outcome-top">当前需求：{{ isRequirementData.requirementName }}</p>
        <p class="online-outcome-top">
          上线结果：<span :style="{ color: requirementOnlineStatus(isRequirementData.requirementOnlineStatus).color }">{{
            requirementOnlineStatus(isRequirementData.requirementOnlineStatus).text }}</span>
        </p>
        <p class="online-outcome-top" v-if="isRequirementData.requirementOnlineMsg !== ''">
          说明：
          <span>{{ isRequirementData.requirementOnlineMsg ? isRequirementData.requirementOnlineMsg : "无" }}</span>
        </p>
      </div>
      <div v-if="offlineToEndContentForm.length == 0" style="color: red">
        无人参与，无须评价
      </div>
      <div class="online-box" v-if="offlineToEndContentForm.length > 0">
        <el-form style="padding-top: 10px;" v-if="(userAuthId == '555' || userAuthId == '888' || userAuthId == '999')">
          <el-form-item label="处理人自评分配比："
            :rules="[{ required: true, message: '必填，且不为0', trigger: ['blur', 'change'] }]">
            <el-input-number size="defalut" :disabled="!isOnlineContent" v-model.number="devMyNumberAvgNumber"
              :precision="0"></el-input-number>
          </el-form-item>
        </el-form>
        <el-form class="online-form-box" :model="offlineToEndContentForm">
          <ul class="online-form-ul">
            <li class="online-form-li" v-for="(item, index) in offlineToEndContentForm" :key="item.ID">
              <!-- 上线参与人员及内容 -->
              <div class="online-form-content online-form-content-top">
                <div class="online-form-info online-form-info-left">
                  <p style="width: 96px;">{{ isTsContent(item.isTs)?.content }}参与人：</p>
                  <p>{{ item.userName }}</p>
                </div>
                <div class="online-form-info">
                  <p class="online-info-title" style="width: 96px;">任务内容：</p>
                  <el-input class="online-content-box" disabled v-model="item.processJob"></el-input>
                </div>
              </div>

              <!-- 填写内容 -->
              <div class="online-form-content">
                <el-form-item class="online-form-info-left" label="评分："
                  :prop="`offlineToEndContentForm.${index}.bearBossUserTPNumber`" label-width="96px">
                  <el-input-number size="defalut" :disabled="!isOnlineContent"
                    v-model.number="offlineToEndContentForm[index].bearBossUserTPNumber"
                    :precision="0"></el-input-number>
                </el-form-item>
                <el-form-item class="online-form-info-left" label="实际耗时："
                  :prop="`offlineToEndContentForm.${index}.actualTime`" label-width="96px">
                  <el-input-number size="defalut" :disabled="!isOnlineContent"
                    v-model.number="offlineToEndContentForm[index].actualTime" :precision="0"></el-input-number>
                </el-form-item>
              </div>
              <div class="online-form-content">
                <el-form-item class="online-form-info-right" size="samll" label="上线评语："
                  :prop="`offlineToEndContentForm.${index}.bearBossContent`" label-width="96px">
                  <el-input type="textarea" :rows="2" v-model="offlineToEndContentForm[index].bearBossContent"
                    placeholder="请对上线参与人写下评语" clearable :disabled="!isOnlineContent"></el-input>
                </el-form-item>
              </div>
            </li>
          </ul>
        </el-form>

        <el-form style="padding-top: 10px;" v-if="(userAuthId == '555' || userAuthId == '888' || userAuthId == '999')">
          <el-form-item label="技术负责人对项目经理评分配比："
            :rules="[{ required: true, message: '必填，且不为0', trigger: ['blur', 'change'] }]">
            <el-input-number size="defalut" :disabled="!isOnlineContent" v-model.number="bToMAvgNumber"
              :precision="0"></el-input-number>
            （备注：任务分值：1-100；在这个任务中，我帮项目经理多少）
          </el-form-item>
        </el-form>

      </div>
      <div class="online-operate" v-if="isOnlineContent">
        <el-button type="defalut" @click="handleCloseOnlineContentDialog">取消</el-button>
        <el-button type="primary" @click="submitOnlineToEndForm">提交</el-button>
      </div>
    </el-dialog>

    <!-- 需求详情弹窗 -->
    <!-- <el-dialog v-if="dialogInfoVisible" style="width: 1200px" :close-on-click-modal="false" v-model="dialogInfoVisible"
      @close="handleCloseDialog" @closed="handleCloseDialog" top="8vh">
      <CommonRequirementInfoVue :isRequirementID="isRequirementID" :clearData="clearData" :isComment="true">
      </CommonRequirementInfoVue>
    </el-dialog> -->

    <el-dialog v-if="dialogInfoVisible && !isMobile" style="width: 1200px" :close-on-click-modal="false"
      v-model="dialogInfoVisible" @close="handleCloseDialog" @closed="handleCloseDialog" top="8vh">
      <CommonRequirementInfoVue :isRequirementID="isRequirementID" :clearData="clearData" :isComment="true">
      </CommonRequirementInfoVue>
    </el-dialog>

    <!-- 关闭/撤回原因 -->
    <el-dialog top="30vh" v-model="dialogReasonMsgVisible"
      :title="isRequirementData?.requirementFatherStatus == 9 ? '撤回原因：' : '关闭原因：'">
      <el-form>
        <el-form-item>
          <el-input type="textarea" rows="4" maxlength="200" show-word-limit v-model="reasonMsg"
            placeholder="请输入原因......">
          </el-input>
        </el-form-item>
        <el-form-item>
          <div class="dialog-footer">
            <el-button type="defalut" @click="handleCloseReasonMsgDialog">取消</el-button>
            <el-button type="primary" @click="handleSubmitReasonMsg">确定</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 关联文件 -->
    <AssRequiremenFileVue v-model:isOpen="openModal" @add-files="handleAddFiles"></AssRequiremenFileVue>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive, computed, nextTick } from "vue";
import { ElMessage, ElMessageBox, FormInstance } from "element-plus";
import { Delete, Loading } from '@element-plus/icons-vue'
import { ElForm } from "element-plus";
import {
  putCloseRequirementStatus,
  PostOfflineToEnd,
  GetGetBareUsersMsgs,
  PutOnlineEndBearContents,
  PutReturnCloseFatherRequirementStatus,
  postNewInitRequirement,
  postNewAvgRequirement,
} from "@/api/newDemands/index";
import { PutUpdateGetTest } from "@/api/common/index";
import { handleUploadRequirement } from "@/utils/common";
import { handleStringNames, isTsContent, handleFileName } from "@/utils/utils";
import {
  fatherStatus,
  isValidateString,
  validateInput,
  requirementOnlineStatus,
  taskTypeContent, timeToData,
} from "@/utils/utils";
import useCommonDataStore from "@/store/common/common";
import CommonRequirementInfoVue from "@/components/requirement/comomRequirementInfo.vue";
import AssRequiremenFileVue from '@/components/requirement/assRequiremenFile.vue';
import UploadFilesVue from "@/components/requirement/uploadFiles.vue";
import { useRouter } from 'vue-router';
const router = useRouter();

let useCommonStore = useCommonDataStore();
const loading = ref(false);
const userAuthId = ref<any>(null); //当前用户权限id
const allRequirements = ref<any>([]); // 我负责的所有需求
const endTime = ref(null); //需求结束时间
const searchFormData = ref({
  projectTitle: "",
  userName: "",
  time: [null, null],
  tag: "", // 新增标签筛选
});

// 更健壮的标签提取方法
const extractTagsFromRequirements = (requirements: any[]) => {
  const tags = new Set<string>();

  requirements.forEach(req => {
    // 更灵活的正则匹配，适应不同格式
    const matches = req.requirementName.match(/【(.*?)】/g) || [];
    if (matches.length > 0) {
      // 取最后一个【】中的内容作为标签
      const tag = matches[1].replace(/【|】/g, '').trim();
      if (tag) tags.add(tag);
    }
  });

  return Array.from(tags).sort();
};

// 根据标签筛选需求
const handleTagFilter = () => {
  if (!searchFormData.value.tag) {
    // 如果清空标签筛选，恢复显示所有数据
    allRequirements.value = [...allOriginalRequirements.value];
  } else {
    // 应用标签筛选
    allRequirements.value = allOriginalRequirements.value.filter(req => {
      // 找到所有【】内容
      const matches = req.requirementName.match(/【(.*?)】/g) || [];
      // 检查是否存在第二个【】
      if (matches.length >= 2) {
        // 提取第二个【】内的内容（数组索引为1）
        const secondTag = matches[1].replace(/【|】/g, '').trim();
        return secondTag === searchFormData.value.tag;
      }

      // 如果没有第二个【】则过滤掉
      return false;
    });
  }

  if (allRequirements.value.length > 0) {
    // 1、将响应数据根据requirementFatherStatus进行分类并统计
    const statusCount = {} as any;

    allRequirements.value.forEach((item: any) => {
      // let fatherStatus = item.requirementFatherStatus;
      let fatherStatus = item.requirementFatherStatus;

      if (statusCount[fatherStatus]) {
        statusCount[fatherStatus].total++;
        // 判断该item是否已经添加
        if (!statusCount[fatherStatus].requirements.includes(item.ID)) {
          statusCount[fatherStatus].requirements.push(item);
        }
      } else {
        statusCount[fatherStatus] = {
          status: Number(fatherStatus),
          total: 1,
          requirements: [item],
        };
      }
    });

    allRequirements.value = Object.values(statusCount);
    // 动态添加样式
    const cardLayoutBox = document.getElementById("cardLayoutBox");
    let length = allRequirements.value.legnth;
    if (length % 3 == 0) {
      cardLayoutBox?.style.setProperty("justify-content", "space-between");
    } else {
      cardLayoutBox?.style.setProperty("justify-content", "flex-start");
    }
    loading.value = false;
  }
};

// 添加移动端检测逻辑
const isMobile = computed(() => {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
});


const dialogAvgVisible = ref(false); //控制是否开启分配任务弹窗
const dialogInfoVisible = ref(false); //查看需求弹窗控件
const clearData = ref(false); //控制是否清空子组件数据
const dialogRecordVisible = ref(false); //控制查看审核记录弹窗控件
const dialogDesignFileVisible = ref(false); //控制上传概要设计控件
const dialogIsGetTestPMTipVisible = ref(false); //控制是否需要测试参与和评价弹窗
const dialogOfflineToEndVisible = ref(false); //控制上线结果弹窗控件
const dialogOfflineEndCotentVisible = ref(false); //控制上线评论弹窗控件

const isRequirementID = ref(); //当前操作任务ID
const isRequirementData = ref<any>(null); //当前需求数据
const allDevNameOptions = ref(); //所有研发人员列表
const allMsNameOptions = ref(); //所有运维人员列表
const allTestNameOptions = ref(); //所有测试人员列表
const summaryFileText = ref([]); //概要设计文件显示
const summaryFilePath = ref<any>([]); //概要设计文件地址
const recordData = ref<any>([]); //所有审核记录
const filePaths = ref<any>("");//概要设计文件

/* 技术负责人选择是否测试参与及对项目经理、需求的评分 */
const isGetTestPMTipRef = ref<FormInstance>();
const isGetTestPMTipRules = reactive({
  itemRequirementPMTip: [
    {
      required: true,
      message: "必填",
      trigger: "blur",
      validator: validateInput,
    },
  ],
  itemRequirementPMNumber: [
    {
      required: true,
      message: "必填",
      trigger: "blur",
    },
  ],
  itemRequirementProjectPMTip: [
    {
      required: true,
      message: "必填",
      trigger: "blur",
      validator: validateInput,
    },
  ],
  itemRequirementProjectPMNumber: [
    {
      required: true,
      message: "必填",
      trigger: "blur",
    },
  ],
});
const isGetTestPMTipForm = ref<any>({
  itemRequirementId: null,
  isGetTest: 3,
  itemRequirementPMTip: "",
  itemRequirementPMNumber: 100,
  itemRequirementProjectPMTip: "",
  itemRequirementProjectPMNumber: 100,
});

const devsRequirementFormData = reactive<any>([
]); // 已分配研发人员列表
const msRequirementFormData = reactive<any>([
]); // 已分配运维人员列表
const tsRequirementFormData = reactive<any>([
]); // 已分配测试人员列表

// * 技术负责人提交上线结果
const offlineToEndFomrRef = ref<FormInstance>(); //技术负责人提交上线结果表单实例
const isOfflineToEnd = ref(false); // 上线是否通过
// 上线结果表单校验规则
const offlineToEndFormRules = reactive({
  requirementOnlineMsg: [
    {
      required: isOfflineToEnd.value,
      message: "必填",
      trigger: "blur",
      validator: (_: any, value: any, callback: any) => {
        if (isValidateString(value)) {
          callback(new Error("必填，且不能为空格或空行！"));
        } else {
          callback();
        }
      },
    },
  ],
});
// 上线结果表单数据
const offlineToEndForm = ref<any>({
  requirementId: null,
  requirementOnlineStatus: 2,
  requirementOnlineMsg: "",
});

const offlineToEndContentForm = ref<any>([]); // 上线评分提交数据
const devMyNumberAvgNumber = ref(0);// 处理人自评分配比
const bToMAvgNumber = ref(0);// 技术负责人对项目经理评分配比
const isOnlineContent = ref(true); // 是否提交评论：true-提交；false-查看

// * 关闭/撤回需求
const dialogReasonMsgVisible = ref(false);// 关闭/撤回需求原因弹窗
const reasonMsg = ref("");// 关闭/撤回需求原因

// TODO 关联文件
const openModal = ref(false);
const newAssFilesList = ref<any>([]);// 新关联的文件

//* 上传文件初始配置
const initConfig = {
  tipText: "",// 提示文本
  type: "primary",// 按钮类型
  plain: true,// 按钮样式
  btnText: "上传文件",// 按钮文本
  fileUrl: "/file/upload_file",// 上传地址
  fileType: "summaryWorld",// 上传类型
  fileTypeId: "5",// 上传类型id
};
const resetFiles = ref(false);// 是否清除已上传文件列表



// 在data部分添加
const allTags = ref<string[]>([]); // 所有标签列表
const allOriginalRequirements = ref<any[]>([]); // 保存原始数据

// 懒加载相关状态
const statusLoadingStates = ref<Record<number, boolean>>({}); // 每个状态的加载状态
const statusPageStates = ref<Record<number, number>>({}); // 每个状态的当前页码
const statusHasMoreStates = ref<Record<number, boolean>>({}); // 每个状态是否还有更多数据
const statusScrollStates = ref<Record<number, boolean>>({}); // 每个状态是否正在滚动加载

// 初始化状态数据
const initStatusData = () => {
  for (let i = 1; i <= 9; i++) {
    statusLoadingStates.value[i] = false;
    statusPageStates.value[i] = 1;
    statusHasMoreStates.value[i] = true;
    statusScrollStates.value[i] = false;
  }
};

// 获取指定状态的需求数据
const getRequirementsByStatus = async (status: number, isLoadMore = false) => {
  if (statusLoadingStates.value[status] || (!isLoadMore && !statusHasMoreStates.value[status])) {
    return;
  }

  statusLoadingStates.value[status] = true;
  statusScrollStates.value[status] = isLoadMore;

  try {
    const { data } = await postNewInitRequirement({
      projectTitle: searchFormData.value.projectTitle,
      beginTime: searchFormData.value.time === null ? null : searchFormData.value.time[0],
      endTime: searchFormData.value.time === null ? null : searchFormData.value.time[1],
      requirementStatus: status,
      page: statusPageStates.value[status],
      pageSize: 10,
      keyword: searchFormData.value.userName || ""
    });

    if (data.code === 200) {
      const responseData = data.data || {};
      const newRequirements = responseData.list || [];
      const total = responseData.total || 0;
      
      // 更新对应状态的数据
      const existingStatusIndex = allRequirements.value.findIndex((item: any) => item.status === status);
      
      if (existingStatusIndex >= 0) {
        // 如果已存在该状态，追加数据
        if (isLoadMore) {
          allRequirements.value[existingStatusIndex].requirements = [
            ...allRequirements.value[existingStatusIndex].requirements,
            ...newRequirements
          ];
        } else {
          allRequirements.value[existingStatusIndex].requirements = newRequirements;
          allRequirements.value[existingStatusIndex].total = total;
        }
      } else {
        // 如果不存在该状态，添加新状态
        allRequirements.value.push({
          status: status,
          total: total,
          requirements: newRequirements
        });
      }

      // 更新分页状态
      const currentStatusIndex = existingStatusIndex >= 0 ? existingStatusIndex : allRequirements.value.length - 1;
      const currentLoadedCount = allRequirements.value[currentStatusIndex]?.requirements.length || 0;
      
      if (newRequirements.length < 10 || currentLoadedCount >= total) {
        statusHasMoreStates.value[status] = false;
      } else {
        statusPageStates.value[status] += 1;
      }
    } else {
      ElMessage.error(data.msg);
    }
  } catch (error) {
    console.error(`获取状态${status}需求失败:`, error);
    ElMessage.error(`获取状态${status}需求失败`);
  } finally {
    statusLoadingStates.value[status] = false;
    statusScrollStates.value[status] = false;
  }
};

// 懒加载处理函数
const handleScroll = (status: number) => {
  const cardListBox = document.getElementById(`card-list-box-${status}`);
  if (!cardListBox) return;

  const { scrollTop, scrollHeight, clientHeight } = cardListBox;
  const isNearBottom = scrollTop + clientHeight >= scrollHeight - 10;

  if (isNearBottom && statusHasMoreStates.value[status] && !statusLoadingStates.value[status]) {
    getRequirementsByStatus(status, true);
  }
};

// TODO 获取用户负责的所有需求
const getAllRequirements = async () => {
  loading.value = true;
  userAuthId.value = localStorage.getItem("authorityId");
  
  // 重置所有状态数据
  initStatusData();
  allRequirements.value = [];

  // 并行获取所有状态的数据
  const promises = [];
  for (let i = 1; i <= 9; i++) {
    promises.push(getRequirementsByStatus(i, false));
  }

  try {
    await Promise.all(promises);
    
    // 按状态排序
    allRequirements.value.sort((a: any, b: any) => a.status - b.status);
    
    // 提取标签
    const allRequirementsList = allRequirements.value.flatMap((statusGroup: any) => statusGroup.requirements);
    allTags.value = extractTagsFromRequirements(allRequirementsList);
    
    // 动态添加样式
    nextTick(() => {
      const cardLayoutBox = document.getElementById("cardLayoutBox");
      if (cardLayoutBox) {
        const length = allRequirements.value.length;
        if (length % 3 === 0) {
          cardLayoutBox.style.setProperty("justify-content", "space-between");
        } else {
          cardLayoutBox.style.setProperty("justify-content", "flex-start");
        }
      }
    });
  } catch (error) {
    console.error("获取需求数据失败:", error);
    ElMessage.error("获取需求数据失败");
  } finally {
    loading.value = false;
  }
};

// 查看需求
const handleRowClick = async (id: number) => {
  if (isMobile.value) {
    // 移动端跳转到新页面
    router.push({ path: `/requirement/${id}` });
  } else {
    // PC端弹框展示
    dialogInfoVisible.value = true;
    isRequirementID.value = id;
  }
};

// ! 操作
const handleCommand = async (val: any) => {
  isRequirementID.value = val.requirement.ID;
  isRequirementData.value = val.requirement;

  switch (val.operate) {
    case 1:
      // 研发负责人创建的需求-未上传概要设计
      if (isRequirementData.value.itemRequirementWorldSummary == "" && userAuthId.value !== "111" && (isRequirementData.value.taskType == 1 || isRequirementData.value.taskType == 3)) {
        // 上传概要设计
        dialogDesignFileVisible.value = true;
      } else if (isRequirementData.value.isGetTest == 3 && (isRequirementData.value.requirementCreateName !== '刘涛' && isRequirementData.value.requirementCreateName !== '胡文斌')) {
        // 是否需要测试参与并评分
        dialogIsGetTestPMTipVisible.value = true;
      } else {
        // 分配
        dialogAvgVisible.value = true;
      };


      // 如果用户是研发负责人
      if (userAuthId.value !== "111") {
        await useCommonStore.getAllRoleUsersList("111|222|555|666|777|999");
        allDevNameOptions.value = useCommonStore.$state.allRoleUserList;
        allMsNameOptions.value = useCommonStore.$state.allRoleUserList;
      } else {
        // 如果用户为测试负责人
        await useCommonStore.getAllRoleUsersList("111|222|555|666|777|999");

        allTestNameOptions.value = useCommonStore.$state.allRoleUserList;
      }
      break;
    case 7:
      ElMessage.info("待上线");
      break;
    case 8:
      // ElMessage.info("已上线");
      if (val.operate2 == 1) {
        // 评价或查看评价
        await handleOpenOfflineToEndContent(isRequirementID.value);
      } else if (val.operate2 == 2) {
        // 提交上线结果
        offlineToEndForm.value.requirementId = isRequirementID.value;
        dialogOfflineToEndVisible.value = true;
      }
      break;
    case 9:
      dialogReasonMsgVisible.value = true;
      break;
    default:
      dialogReasonMsgVisible.value = true;
      break;
  }
};

// TODO 关闭弹窗并重置表单数据
const handleCloseResetDialog = () => {
  isGetTestPMTipForm.value = {
    itemRequirementId: null,
    isGetTest: 3,
    itemRequirementPMTip: "",
    itemRequirementPMNumber: 100,
    itemRequirementProjectPMTip: "",
    itemRequirementProjectPMNumber: 100,
  };
  isGetTestPMTipRef.value?.resetFields();
  dialogIsGetTestPMTipVisible.value = false;
};

// TODO 技术负责人判断是否需求测试参与，对项目经理和需求评价及评分
const submitIsGetTestPMTipForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async (valid, fileds) => {
    if (valid) {
      isGetTestPMTipForm.value.itemRequirementId = isRequirementID.value;

      if (isGetTestPMTipForm.value.isGetTest !== 2) {
        ElMessageBox.confirm("确定不需要测试参与吗？", "warning", {
          cancelButtonText: "取消",
          confirmButtonText: "确定",
          type: "warning"
        }).then(async () => {
          isGetTestPMTipForm.value.isGetTest == 1;
          const { data } = await PutUpdateGetTest(isGetTestPMTipForm.value);
          if (data.code === 200) {
            ElMessage.success(data.msg);
            handleCloseResetDialog();
            // dialogAvgVisible.value = true;
            loading.value = true;
            await getAllRequirements();
            loading.value = false;
          } else {
            ElMessage.error(data.msg);
            throw console.error(fileds);
          }
        }).catch(() => {
          return;
        });
      } else {
        const { data } = await PutUpdateGetTest(isGetTestPMTipForm.value);
        if (data.code === 200) {
          ElMessage.success(data.msg);
          handleCloseResetDialog();
          loading.value = true;
          await getAllRequirements();
          loading.value = false;
        } else {
          ElMessage.error(data.msg);
          throw console.error(fileds);
        }
      }
    } else {
      throw console.error(fileds);
    }

  })
};

// 接收子组件中上传的文件地址
const handleUpdateFilePaths = (value: any) => {
  summaryFilePath.value = value;
};

// 上传概要设计后将文件与需求绑定
const handleDesignFile = async (id: number) => {
  dialogDesignFileVisible.value = true;
  if (summaryFilePath.value.length == 0 && newAssFilesList.value.length == 0) {
    ElMessage.warning("必须上传概要设计");
    return;
  } else {
    // 将文件地址用"|"拼接成字符串
    if (summaryFilePath.value.length > 0 && newAssFilesList.value.length > 0) {
      filePaths.value = summaryFilePath.value.map((item: any) => item).join('|') + '|' + newAssFilesList.value.join('|');
    } else {
      if (summaryFilePath.value.length === 0) {
        filePaths.value = newAssFilesList.value.join('|');
      } else {
        filePaths.value = summaryFilePath.value.map((item: any) => item).join('|');
      }
    }

    await handleUploadRequirement({
      itemRequirementId: id,
      fileType: 2,
      draftPath: null,
      summaryPath: filePaths.value,
      detailedPath: null,
      meetingPath: null,
      onLineMeetingPath: null,
    }).then(async () => {
      dialogDesignFileVisible.value = false;
      summaryFilePath.value = [];
      summaryFileText.value = [];
      dialogIsGetTestPMTipVisible.value = true;
      loading.value = true;
      await getAllRequirements();
      loading.value = false;
    }).catch((error) => {
      ElMessage.error("上传失败！");
      throw console.error(error);
    });
  }
};


// TODO 新增分配人员行
const handleAddFormData = (val: any) => {
  if (val === 1) {
    devsRequirementFormData.push({
      userUUID: "",
      guessTime: "",
      processJob: "",
      guessProcess: null,
      processJobNum: null,
    });
  };

  if (val === 2) {
    msRequirementFormData.push({
      userUUID: "",
      guessTime: "",
      processJob: "",
      guessProcess: null,
      processJobNum: null,
    });
  };

  if (val === 3) {
    tsRequirementFormData.push({
      userUUID: "",
      guessTime: "",
      processJob: "",
      guessProcess: null,
      processJobNum: null,
    });
  }
};
// TODO 删除分配人员行
const handleDelFormData = (index: number, del: number) => {
  switch (del) {
    // 分配前删除研发人员
    case 1:
      devsRequirementFormData.splice(index, 1);
      return devsRequirementFormData;
    // 分配前删除测试人员
    case 2:
      msRequirementFormData.splice(index, 1);
      return msRequirementFormData;
    // 分配前删除测试人员
    case 3:
      tsRequirementFormData.splice(index, 1);
      return tsRequirementFormData;
    // }
  }
};
// TODO 规定预计上线时间为today及之后，之前的不可选
const disabledDate = (time: any) => {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return time.getTime() < today.getTime();
};

// TODO 关闭弹窗
const handleCloseDialog = () => {
  devsRequirementFormData.length = 0;
  msRequirementFormData.length = 0;
  tsRequirementFormData.length = 0;
  summaryFileText.value = [];
  summaryFilePath.value = [];
  dialogDesignFileVisible.value = false;
  dialogRecordVisible.value = false;
  recordData.value = [];
  clearData.value = true;
  newAssFilesList.value = [];
  filePaths.value = "";

  resetFiles.value = true;
  setTimeout(() => {
    resetFiles.value = false;
  }, 100)
};

// TODO 关闭分配弹窗
const handleCloseAssDialog = () => {
  devsRequirementFormData.length = 0;
  msRequirementFormData.length = 0;
  tsRequirementFormData.length = 0;
  endTime.value = null;
  dialogAvgVisible.value = false;
};

// 分配研发人员动态添加禁选功能
const isDisabled = (testUuid: any, selectedUuid: any, val: number) => {
  if (val === 1) {
    // devsRequirementFormData
    return devsRequirementFormData.some(
      (formItem: any) =>
        formItem.userUUID === testUuid && formItem.userUUID !== selectedUuid
    );
  } else if (val === 2) {
    return msRequirementFormData.some(
      (formItem: any) =>
        formItem.userUUID === testUuid && formItem.userUUID !== selectedUuid
    );
  } else {
    // 分配测试人员动态添加禁选功能
    // 检查当前测试人员UUID是否已经在tsRequirementFormData中被选中
    return tsRequirementFormData.some(
      (formItem: any) =>
        formItem.userUUID === testUuid && formItem.userUUID !== selectedUuid
    );
  }
};

// 自定义验证函数
const validateFormData = () => {
  if ((endTime.value === null && (userAuthId.value == '555' || userAuthId.value == '888' || userAuthId.value == '999')) || (isRequirementData.value.requirementCreateName == '刘涛' && endTime.value === null) || (isRequirementData.value.requirementCreateName == '胡文斌' && endTime.value === null)) {
    return {
      valid: false,
      message: "验证失败，结束时间必填",
    };
  } else {
    return {
      valid: true,
      message: "验证通过",
    }
  }
};

// TODO 提交分配任务功能
const handleConfirmAvg = async () => {
  const result = computed(() => validateFormData()).value;

  if (result.valid) {
    let postFormData = {
      itemRequirementId: isRequirementID.value,
      endTime: endTime.value,
      devs: devsRequirementFormData,
      ms: msRequirementFormData,
      ts: tsRequirementFormData,
    };

    // 1、发起分配需求请求
    const { data } = await postNewAvgRequirement(postFormData);
    if (data.code === 200) {
      // 2、请求成功后关闭弹窗并重新获取任务数据
      dialogAvgVisible.value = false;

      loading.value = true;


      await getAllRequirements();
      loading.value = false;
    } else {
      ElMessage.error(data.msg);
      throw console.error(data.msg);
    }
  } else {
    ElMessage.warning(result.message);
    return;
  }
};

// // 上线
// TODO 关闭上线结果弹窗
const handleCloseOnlineDialog = () => {
  // 清空上线结果数据
  offlineToEndForm.value = {
    requirementId: null,
    requirementOnlineStatus: 2,
    requirementOnlineMsg: "",
  };
  offlineToEndFomrRef.value?.resetFields();
  dialogOfflineToEndVisible.value = false;
};

// TODO 关闭上线评分弹窗
const handleCloseOnlineContentDialog = () => {
  // 清空上线评语数据
  offlineToEndContentForm.value = [];
  devMyNumberAvgNumber.value = 0;
  isOnlineContent.value = true;
  dialogOfflineEndCotentVisible.value = false;
  bToMAvgNumber.value = 0;
};

// TODO 开启上线评分弹窗
const handleOpenOfflineToEndContent = async (id: number) => {
  // await getAllRequirements();

  // 获取待评价人员列表
  const { data } = await GetGetBareUsersMsgs(id);
  if (data.code === 200) {
    offlineToEndContentForm.value = data.data.submitOnlieEndBareBeans;
    devMyNumberAvgNumber.value = data.data.devMyNumberAvg;

    // 上线参与研发
    if (userAuthId.value == "555" || userAuthId.value == "999") {

      if (isRequirementData.value.tipDevOnlineStatus == 1) {
        isOnlineContent.value = true;
      } else {
        isOnlineContent.value = false;
      }

    } else if (userAuthId.value == "111") {

      if (isRequirementData.value.tipTsOnlineStatus == 1) {
        isOnlineContent.value = true;
      } else {
        isOnlineContent.value = false;
      }

    } else if (userAuthId.value == '888' || userAuthId.value == '999') {

      isOnlineContent.value = false;
    }
    bToMAvgNumber.value = data.data.bToMAvgNumber;
    dialogOfflineEndCotentVisible.value = true;
  } else {
    ElMessage.error(data.msg);
    throw console.error(data.msg);
  }
};

// TODO 提交上线结果
const handleSubmitOffline = async () => {
  isOfflineToEnd.value = offlineToEndForm.value.requirementOnlineStatus == 3 ? true : false;

  // 上线失败
  if (isOfflineToEnd.value) {
    // 失败原因说明必填
    if (offlineToEndForm.value.requirementOnlineMsg.trim() == "") {
      ElMessage.warning("请填写失败原因！");
      return;
    } else {
      const { data } = await PostOfflineToEnd(offlineToEndForm.value);
      if (data.code === 200) {
        ElMessage.success(data.msg);
        await handleOpenOfflineToEndContent(isRequirementID.value);
        handleCloseOnlineDialog();

        loading.value = true;
        await getAllRequirements();
        loading.value = false;
      } else {
        ElMessage.error(data.msg);
        throw console.error(data.msg);
      }
    }
  } else {
    // 上线成功，说明不必填
    const { data } = await PostOfflineToEnd(offlineToEndForm.value);
    if (data.code === 200) {
      ElMessage.success(data.msg);
      await handleOpenOfflineToEndContent(isRequirementID.value);
      handleCloseOnlineDialog();

      loading.value = true;
      await getAllRequirements();
      loading.value = false;
    } else {
      ElMessage.error(data.msg);
      throw console.error(data.msg);
    }
  }
};

// TODO 提交上线评论
const submitOnlineToEndForm = async () => {
  const submitData = offlineToEndContentForm.value.map((item: any) => {
    return {
      // requirementBearId: item.ID,
      bearBossContent: item.bearBossContent,
      bearBossUserTPNumber: Number(item.bearBossUserTPNumber),
      actualTime: Number(item.actualTime),
      requirementChildId: item.ID,
    };
  });

  const valid = submitData.every((item: any) => {
    // 校验是否有评语为空
    if (isValidateString(item.bearBossContent)) {
      ElMessage.error("每条评论都必填，且不能为空");
      return false;
    }

    // 校验评分是否≤0
    if (
      isNaN(item.bearBossUserTPNumber) ||
      item.bearBossUserTPNumber < 0 || item.bearBossUserTPNumber == 0) {
      ElMessage.error("评分必填,且不能为0");
      return false;
    }

    // 如果所有校验通过
    return true;
  });
  if ((valid && ((userAuthId.value == '555' || userAuthId.value == '888' || userAuthId.value == '999'))) || (valid && (userAuthId.value == '111'))) {

    const { data } = await PutOnlineEndBearContents({
      requirementId: isRequirementID.value,
      bToMAvgNumber: bToMAvgNumber.value,
      devMyNumberAvg: devMyNumberAvgNumber.value,
      submitOnlieEndBareBeans: submitData,

    });
    if (data.code === 200) {
      ElMessage.success(data.msg);
      handleCloseOnlineContentDialog();
      loading.value = true;
      await getAllRequirements();
      loading.value = false;
    } else {
      ElMessage.error(data.msg);
      throw console.error(data.msg);
    }
  } else {
    return;
  }
};

// TODO 取消关闭/撤回需求弹窗
const handleCloseReasonMsgDialog = () => {
  reasonMsg.value = "";
  dialogReasonMsgVisible.value = false;
};

// TODO 提交关闭/撤回需求原因
const handleSubmitReasonMsg = async () => {
  if (isValidateString(reasonMsg.value)) {
    ElMessage.warning("必填，且不能为空或空格。");
    return;
  } else {
    const reasonMsgForm = {
      requirementId: isRequirementID.value,
      closeMsg: reasonMsg.value.trim()
    };

    if (isRequirementData.value.requirementFatherStatus == 9) {
      // 撤回需求
      const { data } = await PutReturnCloseFatherRequirementStatus(reasonMsgForm);
      if (data.code !== 200) {
        ElMessage.error(data.msg);
        dialogReasonMsgVisible.value = false;
        return;
      } else {
        handleCloseReasonMsgDialog();
        await getAllRequirements();
      }
    } else {
      // 关闭需求
      const { data } = await putCloseRequirementStatus(reasonMsgForm);
      if (data.code !== 200) {
        ElMessage.error(data.msg);
        dialogReasonMsgVisible.value = false;
        return;
      } else {
        handleCloseReasonMsgDialog();
        await getAllRequirements();
      }
    }
  }
};

// TODO　关联文件
// 监听子组件的事件函数，并接收子组件中选中的文件
const handleAddFiles = (data: any) => {
  newAssFilesList.value = newAssFilesList.value.concat(data);
};
// 删除关联文件
const handleDelAssFile = (row: any) => {
  newAssFilesList.value.splice(newAssFilesList.value.indexOf(row), 1);
};

onMounted(async () => {
  await useCommonStore.getAllRoleUsersList("");
  // getReviewNameOptions();
  getAllRequirements();
});
</script>

<style lang="scss" scoped>
.content-container {
  display: flex;
  flex-direction: column;
  min-width: 1160px;
  height: 100%;
  overflow-x: auto;

  // TODO 搜索区域
  .search-wrap {
    width: 100%;
    //height: 40px;
    margin-bottom: 10px;
    display: flex;
    justify-content: flex-start;

    .search-wrap-item {
      margin-right: 10px;
      margin-bottom: 0;
      min-width: 200px;
      font-weight: bold;
      font-size: 24px;
      font-family: Arial, Helvetica, sans-serif;
      color: #000;
    }
  }

  // 需求列表区域
  .card-layout-box {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    flex-direction: row;
    //flex-wrap: wrap; 换行布局
    overflow-y: auto;
    border-radius: 6px;

    // 无数据时显示
    .card-not-requirement {
      color: #909399;
      margin: auto;
    }

    .card-box {
      //width: 32.6%;
      min-width: 380px;
      //height: 360px;
      height: 97%;
      border: 1px solid #d0d0d0;
      border-radius: 6px;
      margin: 0 0.3% 1% 0.3%;
      display: flex;
      flex-direction: column;
      background: #fff;

      // 列表标题
      .card-header-box {
        width: 100%;
        height: 40px;
        padding: 0 10px;
        line-height: 40px;
        font-size: 14px;
        font-family: Helvetica, Arial, sans-serif;
        //color: white;
        border-radius: 6px 6px 0 0;
        border-bottom: 1px solid #dbdfe0;
        color: #bac0cb;

        span {
          color: #fff;
          font-size: 14px;
        }
      }

      // 列表盒子
      .card-list-box {
        width: 100%;
        // height: calc(100% - 40px);
        display: flex;
        justify-content: flex-start;
        overflow-y: auto;

        .card-list {
          width: 100%;
          height: 100%;
          font-size: 14px;

          .card-list-item {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            border-bottom: 1px solid #ccc;
            width: 100%;
            min-height: 70px;
            //height: 70px;
            padding: 5px;

            // 操作
            .operate-box {
              width: 20px;
              height: 100%;
              display: flex;
              align-items: center;
            }

            .card-list-left {
              width: calc(100% - 20px);
              display: flex;
              flex-direction: column;
              flex-wrap: nowrap;
              justify-content: flex-start;
              position: relative;

              .icon-img {
                position: absolute;
                right: -25px;
                bottom: 0;
              }

              //需求类别
              .card-list-type {
                height: 20px;
                margin-bottom: 5px;

                img {
                  float: left;
                  padding-right: 5px;
                }

                span {
                  float: left;
                  display: inline-block;
                  height: 20px;
                  margin-right: 5px;
                }
              }

              // 需求标题
              .card-header-title-box {
                width: 100%;
                cursor: pointer;

                b {
                  font-size: 15px;
                }

                .el-text {
                  width: 100%;
                }

                .el-text:hover {
                  color: #409eff;
                }
              }

              .card-list-info-box {
                width: 100%;
                display: flex;
                flex-direction: column;

                // 附加信息样式
                .card-list {
                  width: 100%;
                  display: flex;
                  justify-content: space-between;
                  flex-direction: row;
                  white-space: nowrap;
                  padding: 0;
                  font-size: 0.7rem;

                  .card-list-small-item {
                    margin: 0 10px 0 0;
                    position: relative;
                  }

                  .begin-time {
                    width: 110px;
                    font-size: 12px;
                    position: relative;
                  }

                  .item-status {
                    width: 120px;
                  }

                  .boss-name {
                    width: 110px;
                  }

                  .test-list {
                    width: 180px;
                    overflow: hidden;
                    text-overflow: ellipsis;
                  }
                }

                .begin-time {
                  width: 100%;
                  padding: 2px 0;
                  display: flex;
                  flex-direction: row;
                  justify-content: flex-start;

                  .begin-time-first {
                    margin-right: 20px;
                  }
                }

                // .operate-box {
                //   width: 20px;
                //   text-align: right;
                // }
              }

              .card-header-title-box:hover {
                color: #409eff;
              }

              .card-stats {
                font-size: 12px;
                display: flex;
                flex-direction: row;

                span {
                  width: 33%;
                  float: left;
                  padding-left: 5px;
                }
              }
            }
          }
        }
      }
    }

    /* 当屏幕宽度超过 1620px 时，调整 .card-box 的宽度 */
    @media (min-width: 1921px) {
      .card-box {
        width: 24.2%;
        /* 新的宽度 */
      }
    }

    /* 当屏幕宽度超过 2680px 时，调整 .card-box 的宽度 */
    @media (min-width: 2681px) {
      .card-box {
        width: 19.32%;
        /* 新的宽度 */
      }
    }

    .card-list-item:hover {
      background-color: rgb(216.8, 235.6, 255);
    }
  }

  // 审核需求
  .record-title {
    display: flex;
    flex-direction: row;
    padding: 5px 10px;
    margin-bottom: 10px;
    background-color: #f0f0f0;
    border-radius: 2px;

    p {
      margin-right: 20px;
    }
  }

  // 需求草稿
  .info-file-box {
    width: 100%;
    display: flex;
    justify-content: space-between;
    flex-direction: row;
    margin: 10px 0 0;

    .info-content-title {
      width: 100px;
      padding: 0 10px;
    }

    .info-file-ul {
      width: calc(100% - 70px);
      text-align: left;
      display: flex;
      flex-direction: row;

      .info-file-item {
        width: 60px;
        margin-right: 10px;
      }

      .info-file-item:hover {
        color: #409eff;
        cursor: pointer;
      }
    }
  }

  // TODO 分配需求弹窗
  .dialog-container {
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    .dialog-form-title {
      font-weight: bold;
      padding: 10px;
      margin-bottom: 10px;
      // background-color: #f0f0f0;
      background-color: white;
      display: flex;
      justify-content: space-between;
    }

    .dialog-form-box {
      width: 100%;
      display: flex;
      flex-direction: row;
      justify-content: center;
      // justify-content: flex-start;
      margin-bottom: 20px;

      .el-form-item {
        margin: 0 8px;
      }
    }

    .dialog-footer {
      width: 100%;
      text-align: right;
    }
  }

  // TODO 上线评分
  .dialog-online-container {
    margin-top: 20px;

    .online-box {
      width: 100%;
      max-height: 540px;
      overflow-y: auto;
      display: flex;
      flex-direction: column;
      padding: 0 5px 0 0;

      .online-form-box {
        width: 100%;
        max-height: 600px;

        .online-form-ul>.online-form-li {
          border: 1px solid rgb(221.7, 222.6, 224.4);
          border-radius: 5px;
          margin-bottom: 10px;
          display: flex;
          flex-direction: column;
          padding: 10px;

          .online-form-content {
            width: 100%;
            display: flex;
            flex-direction: row;
            align-items: flex-start;

            .online-form-info {
              width: 100%;
              display: flex;
              flex-direction: row;
              justify-content: flex-start;
            }

            .online-form-info-left {
              width: 280px;
              margin-right: 20px;
            }

            .online-form-info-right {
              width: 100%;

              .online-info-title {
                width: 100px;
              }
            }
          }

          .online-form-content-top {
            margin-bottom: 20px;
          }
        }
      }

    }

    .online-operate {
      width: 100%;
      text-align: right;
      margin-top: 20px;
    }

    // 上线结果
    .online-outcome {
      width: 100%;
      border-radius: 5px;
      border: 1px solid rgb(221.7, 222.6, 224.4);
      margin-bottom: 10px;

      .online-outcome-top {
        padding: 5px 10px;
      }
    }
  }

  .dialog-footer {
    width: 100%;
    text-align: right;
  }

  .red-text {
    color: red;
  }

  .red-bj {
    background-color: #fff1f0;
  }

  .card-finished {
    color: #999;
    text-decoration: line-through;
  }

  // 懒加载状态指示器样式
  .loading-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    color: #999;
    font-size: 12px;
    border-bottom: 1px solid #ccc;
    min-height: 50px;
    
    .loading-content {
      display: flex;
      align-items: center;
      justify-content: center;
      
      .el-icon {
        margin-right: 5px;
      }
    }
  }

  .no-more-data {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    color: #ccc;
    font-size: 12px;
    border-bottom: 1px solid #ccc;
    min-height: 50px;
    
    .no-more-content {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
}
</style>
